package whu.cn.whushare.ui.main;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.SparseArray;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SearchView;
import android.widget.TextView;

import com.androidplus.util.ViewMapping;
import com.androidplus.util.ViewMappingUtil;

import java.util.Stack;

import whu.cn.whushare.R;
import whu.cn.whushare.ui.common.BaseActivity;
import whu.cn.whushare.ui.common.MyFavoriteReShowFragment;

import whu.cn.whushare.ui.main.my.FavoriteActivityFragment;
import whu.cn.whushare.ui.main.my.FavoriteConnectionFragment;
import whu.cn.whushare.ui.main.my.FavoritePaperFragment;
import whu.cn.whushare.ui.main.my.FavoriteQuestionFragment;

/**
 * 文件名：MyTabFavoriteActivity
 * 描 述：
 * 作 者：胡平平
 * 时 间：2014/12/27
 */
@ViewMapping(id = R.layout.my_tab_favorite_layout)          //获取MyTabFavoriteActivity的布局文件
public class MyTabFavoriteActivity  extends BaseActivity {
    private FragmentManager mFragmentManager;               //声明FragmentManager
    @ViewMapping(id = R.id.button_one)                      //获取“收藏问题”按钮
    private Button mFirstBtn;
    @ViewMapping(id = R.id.button_two)                      //获取“收藏文章”按钮
    private Button mSecondBtn;
    @ViewMapping(id = R.id.button_three)                    //获取“收藏活动”按钮
    private Button mThirdBtn;
    @ViewMapping(id = R.id.button_four)                     //获取“收藏链接”按钮
    private Button mLastBtn;
    @ViewMapping(id=R.id.top_bar)                           //获取顶部菜单条
    private RelativeLayout mTopBar;
    @ViewMapping(id = R.id.top_title)                       //获取顶部菜单条标题文本框
    public TextView title;
    @ViewMapping(id = R.id.go_back_btn)                     //获取顶部菜单条“返回”按钮
    public ImageView goBack;
    @ViewMapping(id = R.id.top_right_image)                 //获取顶部菜单条右边图像
    public ImageView rightImg;
    @ViewMapping(id = R.id.top_right_txt)                  //获取顶部菜单条右边文本框
    public TextView rightText;
    @ViewMapping(id=R.id.searchView)                     //获取顶部菜单条搜索视图
    public SearchView searchView;

    private final static String[] mTabTags = {"question", "paper", "activities", "connection"};
    private final static String LAST_TAB = "lastTab";   //上次最后的tab

    private SparseArray<Tab> mTabs = new SparseArray<Tab>();//针对hashMap提出，采用折半查找的方式。效率更高。
    private Tab mTabNow;

    private int mLastTabId;



    @SuppressWarnings("all")
    /*
     * 方法名：getStartIntent(Context context)
     * 功 能：获取跳转到当前activity的intent消息
     * 参 数：@param Context context-上下文信息
     * 返回值：@return 跳转到当前activity的intent
     */
    public static Intent getStartIntent(Context context) {
        Intent intent = new Intent(context,MyTabFavoriteActivity.class);
        return intent;
    }

    @Override
    /**
     * 重写父类的方法，初始化当前activity
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initParams();
        initViews();
        initTabs();
        initActions();
        selectFirstTab();
    }

    //初始化参数
    private void initParams() {
    }

    //初始化views
    private void initViews() {
        ViewMappingUtil.mapView(this, this);
        mFragmentManager = getSupportFragmentManager();
    }

    //初始化动作
    private void initActions() {
        goBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goBack();
            }
        });
    }

    //初始化tab
    private void initTabs() {
        Button[] buttons = {mFirstBtn, mSecondBtn, mThirdBtn, mLastBtn};
        View.OnClickListener tabClickListener = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectTab((Integer) v.getTag());
            }
        };

        for (int i = 0; i < buttons.length; i++) {
            buttons[i].setTag(i);
            addTab(new Tab(i, mTabTags[i], buttons[i]));
            // init click actions
            buttons[i].setOnClickListener(tabClickListener);
        }
    }

    //重新回到页面时，需显示上次用户选择的tab
    private void selectFirstTab() {
        // when the Activity is recycled，needing to showing the last tab;
        if (mLastTabId > 0 && mLastTabId <= 3)
            selectTab(mLastTabId);
        else
            selectTab(3);
    }


    /**
     * 方法名：addTab(Tab tab)
     * 功 能：添加Tab(注意视图必须有id否则将抛出异常)
     * 参 数：@param Tab tab - 被添加的tab
     */
    private void addTab(Tab tab) {
        mTabs.put(tab.id, tab);
    }

    /**
     * 方法名：selectTab(int tabId)
     * 功 能：根据tabId跳转到该tabId代表的页面
     * 参 数：@param int tabId - 被选中的tabId
     */
    public void selectTab(int tabId) {
        Tab tab = mTabs.get(tabId);

        // 若选中的Tab没变，则直接返回
        if (mTabNow == tab) {
            return;
        }
        // 若选中的Tab发生变化，则开始一个Fragment事务
        FragmentTransaction transaction = mFragmentManager.beginTransaction();
        if (mTabNow != null) {
            // 隐藏当前Tab
            mTabNow.hide(transaction);
        }
        // 显示被选中的Tab
        tab.show(transaction);

        //执行Fragment事务
        transaction.setTransition(FragmentTransaction.TRANSIT_UNSET);
        transaction.commit();
        mFragmentManager.executePendingTransactions();
        mTabNow = tab;
    }

    @Override
    /**
     * 在Activity被killed之前保存当前activity数据
     * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
     */
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (mTabNow != null)
            outState.putInt(LAST_TAB, mTabNow.id);
    }

    /**
     * 在Fragment显示前做相应的处理，通知Fragment已显示
     * @param fragment - 需要进行处理的fragment
     * @see whu.cn.whushare.ui.common.MainReShowFragment#onReShow(whu.cn.whushare.ui.main.MainTabActivity)
     */
    private void beforeShowFragment(MyFavoriteReShowFragment fragment) {
        // 通知Fragment已显示
        fragment.onReShow(this);
    }

    /**
     * Tab类
     */
    private class Tab {
        //tab的id和tag
        private int id;
        private String tag;

        //子Fragment栈
        private Stack<FragmentWrapper> fragments = new Stack<FragmentWrapper>();

        private TextView view;

        //构造函数，对tab进行初始化
        private Tab(int id, String tag, TextView view) {
            this.id = id;
            this.tag = tag;
            this.view = view;
            init();
        }

        /**
         * 初始化Tab
         */
        private void init() {
            FragmentWrapper fragmentWrapper = new FragmentWrapper();
            fragmentWrapper.tag = tag;
            fragmentWrapper.fragment = (MyFavoriteReShowFragment) Fragment.instantiate(MyTabFavoriteActivity.this,
                    getFragmentClass(tag).getName());

            fragments.push(fragmentWrapper);
        }

        /**
         * 显示Tab
         */
        private void show(FragmentTransaction transaction) {
            view.setSelected(true);
            view.setShadowLayer(getResources().getDimension(R.dimen.main_tab_text_shadow_radius), getResources()
                            .getDimension(R.dimen.main_tab_text_shadow_dx),
                    getResources().getDimension(R.dimen.main_tab_text_shadow_dy),
                    getResources().getColor(R.color.main_tab_text_shadow));

            FragmentWrapper fragmentWrapper = fragments.peek();
            MyFavoriteReShowFragment showFragment = fragmentWrapper.fragment;

            beforeShowFragment(showFragment);

            if (showFragment.isAdded()) {
                // 已添加过,直接显示Fragment
                transaction.show(showFragment);
            } else {
                // 未添加过,加入Fragment
                transaction.add(R.id.favorite_fragment_layout, showFragment, this.tag);
            }
        }

        /**
         * 隐藏Tab
         */
        private void hide(FragmentTransaction transaction) {
            // 取消原Tab对应视图的选中状态
            view.setSelected(false);
            view.setShadowLayer(0, 0, 0, 0);
            transaction.hide(mTabNow.getFragment());
        }

        /**
         * 返回当前Tab显示中的Fragment
         * @return MainReShowFragment
         */
        private MyFavoriteReShowFragment getFragment() {
            return this.fragments.peek().fragment;
        }

        /**
         * 方法名：addFragment(String tag, Bundle args)
         * 功 能：将指定类名和参数的fragment添加到group_fragment_layout所在的activity中
         * @param tag - 通过tag获取需要添加的fragment类名
         * @param args - fragment的参数列表
         * @see android.support.v4.app.Fragment#instantiate(android.content.Context, java.lang.String, android.os.Bundle)
         */
        private void addFragment(String tag, Bundle args) {
            FragmentWrapper fragmentWrapper = new FragmentWrapper();
            fragmentWrapper.tag = tag;
            fragmentWrapper.fragment = (MyFavoriteReShowFragment) Fragment.instantiate(MyTabFavoriteActivity.this,
                    getFragmentClass(tag).getName(), args);

            FragmentTransaction ft = mFragmentManager.beginTransaction();
            ft.hide(fragments.peek().fragment);

            // 栈内如果已有此item，则取出前面的item，再把wrapper压回去。
            while (fragments.search(fragmentWrapper) != -1) {
                ft.remove(fragments.pop().fragment);
            }

            ft.add(R.id.favorite_fragment_layout, fragmentWrapper.fragment);
            beforeShowFragment(fragmentWrapper.fragment);
            ft.commit();
            mFragmentManager.executePendingTransactions();
            fragments.push(fragmentWrapper);
        }

        private boolean goBack() {
            if (fragments.size() > 1) {
                FragmentTransaction ft = mFragmentManager.beginTransaction();
                FragmentWrapper fragmentWrapper = fragments.pop();
                MyFavoriteReShowFragment removeFragment = fragmentWrapper.fragment;
                ft.remove(removeFragment);
                FragmentWrapper showFragmentWrapper = fragments.peek();
                MyFavoriteReShowFragment showFragment = showFragmentWrapper.fragment;

                beforeShowFragment(showFragment);
                ft.show(showFragment);
                ft.commit();
                mFragmentManager.executePendingTransactions();
                return true;
            }
            return false;
        }

        private Class<? extends Fragment> getFragmentClass(String tag) {
            Class<? extends Fragment> clazz = null;

            if (tag.equals(mTabTags[0]))
                clazz = FavoriteQuestionFragment.class;
            if (tag.equals(mTabTags[1]))
                clazz = FavoritePaperFragment.class;
            if (tag.equals(mTabTags[2]))
                clazz = FavoriteActivityFragment.class;
            if (tag.equals(mTabTags[3]))
                clazz = FavoriteConnectionFragment.class;

            return clazz;
        }

        private class FragmentWrapper {
            private MyFavoriteReShowFragment fragment;
            private String tag;

            @SuppressWarnings("all")
            @Override
            /**
             * 判断对象o是否为FragmentWrapper的实例，
             * 若对象o是当前FragmentWrapper类返回true，
             * 若对象o不是当前FragmentWrapper类实例返回false，
             * 否则对象o是FragmentWrapper类实例，则根据tag值进行处理
             * 若当前FragmentWrapper类的tag非空，且当前FragmentWrapper类的tag与对象o的tag值相等，返回true；
             * 若当前FragmentWrapper类的tag非空，且当前FragmentWrapper类的tag与对象o的tag值不等，返回false；
             * 若当前FragmentWrapper类的tag为空，且对象o的tag值为空，返回true；
             * 若当前FragmentWrapper类的tag为空，且对象o的tag值非空，返回false；
             * @param o - 需要进行比较的对象
             * @see String#equals(java.lang.Object)
             */
            public boolean equals(Object o) {
                if (this == o) return true;
                if (!(o instanceof FragmentWrapper)) return false;

                FragmentWrapper that = (FragmentWrapper) o;

                if (tag != null ? !tag.equals(that.tag) : that.tag != null) return false;

                return true;
            }

            @Override
            /**
             * 为当前对象返回一个hash码，原则上，若两个对象通过调用equals方法返回true则应分配相同的hash码
             * 若tag非空，则返回tag的hash码，否则返回0
             * @see Object#hashCode()
             */
            public int hashCode() {
                return tag != null ? tag.hashCode() : 0;
            }
        }
    }
}
